# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: helpers\otp\__init__.py
__author__ = "Attila Gerendi (Sanyi)"
import hmac, base64, struct, hashlib, time, binascii


def get_hotp_token(secret, intervals_no, digits=6):
    """
    :param secret: assumes is b32
    :param intervals_no:
    :param digits:
    :return:
    """
    secret = secret.replace(" ", "")
    for _ in range(0, 7):
        try:
            key = base64.b32decode(secret, True)
            break
        except binascii.Error:
            secret += "="

    else:
        raise Exception("something went wrong")

    msg = struct.pack(">Q", intervals_no)
    h = hmac.new(key, msg, hashlib.sha1).digest()
    o = h[19] & 15
    token_base = struct.unpack(">I", h[o : o + 4])[0] & 2147483647
    token = str(token_base % 10 ** digits)
    return "0" * (digits - len(token)) + token


def get_totp_token(secret, window=30, digits=6):
    return get_hotp_token(
        secret, intervals_no=int(time.time()) // window, digits=digits
    )


def get_totp_tokens(secret, intervals, window=30, digits=6):
    """
    returns multiple otp, depending on the intervals (before and after current time) parameter
    For example 1 interval will return 3 tokens, 2 will return 5,
    the results are ordered by time
    :param secret:
    :param intervals:
    :param window:
    :param digits:
    :return:
    """
    result = []
    for i in range(-intervals, intervals + 1):
        result.append(
            get_hotp_token(
                secret,
                intervals_no=int(time.time() + i * window) // window,
                digits=digits,
            )
        )

    return result


if __name__ == "__main__":
    for _ in range(0, 10):
        print(get_totp_tokens(base64.b32encode(b"test").decode(), intervals=1))
        time.sleep(20)
